package com.wall.haven.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.wall.haven.exception.ServiceException;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

public class JsonUtils {
    private static final ObjectMapper DEFAULT_MAPPER = new ObjectMapper();

    public static ObjectMapper getDefaultMapper() {
        return DEFAULT_MAPPER;
    }

    public static TypeFactory getTypeFactory() {
        return DEFAULT_MAPPER.getTypeFactory();
    }


    /**
     * 获取新的ObjectMapper
     *
     * @return {@link ObjectMapper}
     * @author ChenWangKun
     * @date 2023/5/24
     */
    public static ObjectMapper newMapper() {
        return new ObjectMapper();
    }


    /**
     * 对象序列化成json字符串
     * 
     * @param value 
     * @return {@link String}
     * @author ChenWangKun
     * @date 2023/5/6
     */
    public static String toJson(Object value) {
        try {
            return DEFAULT_MAPPER.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new ServiceException("Json序列化失败！", e);
        }
    }

    /**
     * 字符串反序列化成对象
     * 
     * @param jsonStr 对象json字符串
     * @param valueType 对象类型
     * @return T
     * @author ChenWangKun
     * @date 2023/5/6
     */
    public static <T> T fromJson(String jsonStr, Class<T> valueType){
        try {
            return DEFAULT_MAPPER.readValue(jsonStr, valueType);
        } catch (JsonProcessingException e) {
            throw new ServiceException("Json反序列化失败！", e);
        }
    }

    public static <T> T fromJson(InputStream in, Class<T> valueType){
        try {
            return DEFAULT_MAPPER.readValue(in, valueType);
        } catch (IOException e) {
            throw new ServiceException("Json反序列化失败！", e);
        }
    }

    /**
     * 字符串反序列化成对象
     * 解决泛型丢失，示例：
     * this.fromJson(jsonStr, new TypeReference<Map<Integer, List<Integer>>>(){})
     * @param jsonStr 对象json字符串
     * @param valueType 对象类型引用
     * @return T
     * @author ChenWangKun
     * @date 2023/5/6
     */
    public static <T> T fromJson(String jsonStr, TypeReference<T> valueType) {
        try {
            return DEFAULT_MAPPER.readValue(jsonStr, valueType);
        } catch (JsonProcessingException e) {
            throw new ServiceException("Json反序列化失败！", e);
        }
    }

    public static <T> T fromJson(InputStream in, TypeReference<T> valueType) {
        try {
            return DEFAULT_MAPPER.readValue(in, valueType);
        } catch (IOException e) {
            throw new ServiceException("Json反序列化失败！", e);
        }
    }

    /**
     * 类型转化
     *
     * @param obj       源对象
     * @param valueType 目标类型
     * @return {@link T}
     * @author ChenWangKun
     * @date 2023/6/16
     */
    public static <T> T convert(Object obj, Class<T> valueType) {
        return DEFAULT_MAPPER.convertValue(obj, valueType);
    }

    public static <T> T convert(Object obj, TypeReference<T> valueType) {
        return DEFAULT_MAPPER.convertValue(obj, valueType);
    }

    public static <T> T fromMap(Map<String, Object> map, Class<T> valueType) {
        try {
            return DEFAULT_MAPPER.convertValue(map, valueType);
        } catch (Exception e) {
            throw new ServiceException("Json反序列化失败！", e);
        }
    }


}